package mjc.tds;

import java.io.Serializable;
import java.util.Enumeration;
import java.util.Hashtable;

/**
 * Cette classe correspond à notre descripteur
 * de classe, il implémente des méthodes permettant
 * la manipulaton de la classe
 * @author izineela
 */
public class INFOClasse implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	// keys : methodes et attributs
	// value : les droits "public" ou "private"
	private Hashtable<INFOVar, String> attributs = new Hashtable<INFOVar, String>();
	private Hashtable<INFOMethode, String> methodes = new Hashtable<INFOMethode, String>();
	private String droit;
	
	public INFOClasse() {
		// TODO Auto-generated constructor stub
	}
	
	public INFOClasse(String d, Hashtable<INFOVar, String> l_attr, Hashtable<INFOMethode, String> l_methodes){
		setDroit(d);
		attributs = l_attr;
		methodes = l_methodes;
	}
        
 	/**
	 * Coppie de toutes les méthodes et toutes les
  	 * attributs définies dans la classe donnée en paramètre
	 * @param c la classe dont on coppie les informations
	 * @return renvoie la concaténation des deux classes
	 */	
	public INFOClasse ajouterDEFS(INFOClasse classe){
		// ajouer toutes les attributs de la classe 'classe' 
		Enumeration<String> e_t = classe.getAttributs().elements();
		Enumeration<INFOVar> k_t = classe.getAttributs().keys();
		while ( e_t.hasMoreElements() ){
			attributs.put(k_t.nextElement(), e_t.nextElement());
		}
		// ajouter toutes les methodes de la classe 'classe' 
		Enumeration<String> e_m = classe.getMethodes().elements();
		Enumeration<INFOMethode> k_m = classe.getMethodes().keys();
		while ( e_m.hasMoreElements() ){
			methodes.put(k_m.nextElement(), e_m.nextElement());
		}
		return this;
	}
	
	public void ajouterAttribut(String droit, INFOVar att){
		attributs.put(att,droit);
	}
	
	public void ajouterMethode(String droit, INFOMethode methode){
		methodes.put(methode,droit);
	}
	
	/**
	 * Vérifier si une méthode est déjà définie
	 * on ne tient compte que du nom de la méthode
	 * @param nom
	 * @return en cas de succès, il renvoie le 
	 * descripteur de la méthode, sinon null
	 */
	public INFOMethode chercherMethode(String nom){
		INFOMethode res = null ;
		boolean bool = false;
		Enumeration<INFOMethode> e = methodes.keys();
		while ( e.hasMoreElements() && bool ){
			INFOMethode var = (INFOMethode) e.nextElement();
			if ( var.getIdent().equals(nom) ){
				bool = true;
				res = var;
			}
		}
		return res;
	}
	
	public INFO chercherAttribut(String nom){
		INFOVar res = null ;
		boolean bool = false;
		Enumeration<INFOVar> e = attributs.keys();
		while ( e.hasMoreElements() && bool ){
			INFOVar var = (INFOVar) e.nextElement();
			if ( var.getIdent().equals(nom) ){
				bool = true;
				res = var;
			}
		}
		return res;
	}
	
	
	public INFOClasse heriter(){
		// coppie des attributs definies public
		INFOClasse i = new INFOClasse();
		
		Enumeration<String> e = this.attributs.elements();
		Enumeration<INFOVar> k = this.attributs.keys();
		
		while ( e.hasMoreElements() ){
			String value;
			INFOVar key = (INFOVar) k.nextElement();
			value =(String)e.nextElement();
			if ( value.equals("public") ){
				i.ajouterAttribut("public", key);
			}		
		}
		
		Enumeration<String> e2 = this.methodes.elements();
		Enumeration<INFOMethode> k2 = this.methodes.keys();
		while ( e2.hasMoreElements() ){
			String value;
			value =(String)e2.nextElement();
			INFOMethode key = (INFOMethode) k2.nextElement();
			if ( value.equals("public") ){
				i.ajouterMethode("public", key);
			}		
		}
		return i;
		
	}
	/**
	 * @param attributs the attributs to set
	 */
	public void setAttributs(Hashtable<INFOVar, String> attributs) {
		this.attributs = attributs;
	}

	/**
	 * @return the attributs
	 */
	public Hashtable<INFOVar, String> getAttributs() {
		return attributs;
	}

	/**
	 * @param methodes the methodes to set
	 */
	public void setMethodes(Hashtable<INFOMethode, String> methodes) {
		this.methodes = methodes;
	}

	/**
	 * @return the methodes
	 */
	public Hashtable<INFOMethode, String> getMethodes() {
		return methodes;
	}

	public void setDroit(String droit) {
		this.droit = droit;
	}

	public String getDroit() {
		return droit;
	}
	
}
